home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
utilitys
/
makemenu
/
part01
/
makemenu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-04
|
15KB
|
520 lines
/* MakeMenu V1.0 (14-oct-90) - by Hans Jansen
*
* This program will generate C source to build Intuition menus, from
* a simple description file. See MakeMenu.Doc for details on usage.
*
*/
#define DISABLE 0
#define DEFAULT 1
#define ENABLE 1
#define TOGGLE 2
#define CHECK 4
#define SELECT 8
#define CHAR_WIDTH 8
#include <intuition/intuition.h>
#include <stdio.h>
#define NO_ERROR 0
#define ERROR_NO_COMMA 1
#define ERROR_BAD_TEXT 2
#define ERROR_NO_MENU 3
#define ERROR_NO_ITEM 4
#define ERROR_NO_DATA 5
#define ERROR_BAD_NUMBER 6
#define ERROR_BAD_COMMAND 7
#define MAX_LINE 132
char cline[MAX_LINE]; /* input line */
char RecBuf[BUFSIZ]; /* input buffer */
char *ifname, *ofname; /* File name pointers */
FILE *ofile; /* output file handle */
int EndOfFile; /* true = end of file */
int lcnt; /* current input line count */
struct IntuiText *CText; /* Current Text Item pointer */
struct IntuiText *AllText; /* All text items */
struct MenuItem *CItem; /* Current Menu Item */
struct MenuItem *CSItem; /* Current Sub Menu Item */
struct Menu *CMenu, *AllMenu; /* Menu pointers */
main (argc, argv)
int argc; /*number of arguments */
char *argv[]; /*array of ptrs to arg strings */
{
FILE *ifile; /* input File pointer */
int i, j;
int result, error;
char *Scan();
int GetLine();
char *cptr;
char etype[5];
/* get the file names and open the files */
/* initialize input buffers and variables */
AllText = NULL;
CText = NULL;
CMenu = NULL;
CItem = NULL;
CSItem = NULL;
AllMenu = NULL;
result = NO_ERROR;
error = 0;
lcnt = 0;
if (argc != 3)
printf ("usage: MakeMenu <inputfile> <outputfile>\n");
for (ifname = NULL, i=1; i<argc && ifname == NULL; i++)
if ( *argv[i] != '-') ifname = argv[i];
for (ofname = NULL, i=i; i<argc && ofname == NULL; i++)
if ( *argv[i] != '-') ofname = argv[i];
EndOfFile = FALSE; /* no end of file */
ifile = fopen (ifname, "r"); /* open file for reading */
if (ifile == NULL) {
printf (" Cannot open file %s for input!\n", ifname);
exit (10);
};
while ((j = GetLine (ifile, cline, sizeof (cline))) > 0) {
cptr = &cline[0];
for (i = 0; i < sizeof (etype) -1; i++)
etype[i] = toupper (*(cptr + i));
etype[i] = '\0';
cptr = Scan (cptr, ',', TRUE);
if (strcmp ("MENU", etype) == 0)
result = Process_Menu (cptr); /* do a Menu */
else if (strcmp ("ITEM", etype) == 0)
result = Process_Item (cptr, 0); /* do an Item */
else if (strcmp ("SUBI", etype) == 0)
result = Process_Item (cptr, 1); /* do a SubItem */
else
result = ERROR_BAD_COMMAND;
if (result != NO_ERROR) {
error++;
printf (" Line %d has syntax error:%s\n", lcnt, cline);
};
};
fclose (ifile);
if (error == 0) Do_Output ();
}
char *Scan (ptr, c, control)
char *ptr;
char c;
int control;
{
while (*ptr != NULL && ((control && *ptr != c) || (! control && *ptr == c)))
ptr++;
return (ptr); /* return the new pointer */
}
GetLine (fptr, line, lsize) /* get a line from buffer */
FILE *fptr; /* pointer to file to read from */
char line[]; /* destination of characters */
int lsize; /* maximum size for destination */
{
lcnt++; /* bump line count */
if (fgets (line, lsize, fptr) == NULL) {
EndOfFile = TRUE;
return (0);
}
else {
line[strlen (line) - 1] = '\0'; /* discard newline character */
return (strlen (line));
}
}
int Process_Menu (ptr)
char *ptr;
{
char *tptr;
int len;
struct Menu *last;
if (AllMenu == NULL) { /* first menu item */
AllMenu = (struct Menu *) malloc (sizeof (struct Menu));
CMenu = AllMenu; /* Set current pointer */
}
else { /* add new one to list */
last = CMenu;
CMenu = (struct Menu *) malloc (sizeof(struct Menu));
last->NextMenu = CMenu;
};
/* Build Menu structure */
if (*ptr != ',') return (ERROR_NO_COMMA);
ptr++;
/* process disable-flag, if any */
if (*ptr == 'D' || *ptr == 'd')
CMenu->Flags = DISABLE;
else
CMenu->Flags = ENABLE;
ptr = Scan (ptr, ',', TRUE);
if (*ptr != ',') return (ERROR_NO_COMMA);
ptr++;
tptr = Scan (ptr, '\0', TRUE); /* find end of string */
len = tptr-ptr;
CMenu->MenuName = (BYTE *) malloc (len+1);
strcpy (CMenu->MenuName, ptr);
CMenu->NextMenu = NULL;
CMenu->FirstItem = NULL;
CItem = NULL;
CMenu->Width = len + 3 ;
return (NO_ERROR);
}
int Process_Item (ptr, type)
char *ptr;
int type; /* 0 = Item, 1 = SubItem */
{
struct IntuiText *Process_Text();
struct MenuItem *ThisItem;
struct MenuItem *lastI;
struct MenuItem *lastSI;
if (CMenu == NULL) return(ERROR_NO_MENU);
if (type == 1 && CItem == NULL) return(ERROR_NO_ITEM);
if (*ptr != ',') return(ERROR_NO_COMMA);
if (type == 0) { /* Build a MenuItem */
lastI = CItem;
CSItem = NULL; /* clear current Sub Item Flag */
CItem = (struct MenuItem *) malloc (sizeof (struct MenuItem));
if (lastI == NULL) /* First Item for Menu */
CMenu->FirstItem = CItem; /* link it to the menu */
else
lastI->NextItem = CItem; /* link it to the item list */
ThisItem = CItem; /* build it */
}
else { /* Build a SubItem */
lastSI = CSItem;
CSItem = (struct MenuItem *) malloc (sizeof (struct MenuItem));
if (lastSI == NULL) /* First Sub Item for Menu Item */
CItem->SubItem = CSItem; /* link in the sub items */
else
lastSI->NextItem = CSItem;
ThisItem = CSItem;
};
/* Process flags, name, select and command */
ptr++;
ThisItem->Flags = ENABLE;
while (*ptr != ',') {
if (*ptr == 'D' || *ptr == 'd') ThisItem->Flags &= ~ENABLE;
else if (*ptr == 'T' || *ptr == 't') ThisItem->Flags |= TOGGLE;
else if (*ptr == 'C' || *ptr == 'c') ThisItem->Flags |= CHECK;
else if (*ptr == 'S' || *ptr == 's') ThisItem->Flags |= SELECT;
ptr++;
}
ptr++;
ThisItem->ItemFill = (APTR) Process_Text (ptr);
if (ThisItem->ItemFill == NULL) return (ERROR_BAD_TEXT);
ptr = Scan (ptr, ',', TRUE); /* find next comma */
if (*ptr != ',') return (ERROR_NO_COMMA);
ptr++;
/* Select name? */
ThisItem->SelectFill = (APTR) Process_Text (ptr);
ptr = Scan (ptr, ',', TRUE); /* find next comma */
if (*ptr != ',') return (ERROR_NO_COMMA);
ptr++;
/* Command ? */
ThisItem->NextItem = NULL;
ThisItem->SubItem = NULL;
ThisItem->Command = *ptr;
ThisItem->MutualExclude = 0L;
return (NO_ERROR);
}
struct IntuiText *Process_Text (ptr)
char *ptr;
{
struct IntuiText *dptr, *lasText;
char *tptr;
if (*ptr == ',') return (NULL);
lasText = AllText;
while (lasText != NULL) { /* search end of saved-texts list */
CText = lasText;
lasText = lasText->NextText;
};
lasText = CText;
CText = (struct IntuiText *) malloc (sizeof (struct IntuiText));
CText->NextText = NULL;
if( AllText == NULL )
AllText = CText;
else
lasText->NextText = CText;
tptr = Scan (ptr, ',', TRUE);
CText->IText = (UBYTE *) malloc (tptr-ptr+1);
strncpy (CText->IText, ptr, tptr-ptr);
if (CMenu->Width <= tptr-ptr) CMenu->Width = tptr-ptr;
/* check for duplicate, eliminate this one if duplicate */
dptr = AllText;
while (dptr != CText) {
if (strcmp (dptr->IText, CText->IText) == 0 ) {
free ((char *) (CText->IText));
free ((char *) CText);
CText = dptr;
lasText->NextText = NULL;
}
else dptr = dptr->NextText;
}
return (CText);
}
Do_Output()
{
char nxt, quote, Flag[10];
char Mptr[14];
int Menu, Item, left, top, width, height;
int stop;
char rest[60];
ofile = fopen (ofname, "w"); /* open file for writing */
if (ofile == NULL) {
printf (" Cannot open file %s for output!\n", ofname);
exit (10);
}
/* Output the IntuiText structure first */
quote = '"';
fprintf (ofile, "/*****************************************/\n");
fprintf (ofile, "/* This code was generated by: */\n");
fprintf (ofile, "/* MakeMenu V1.0 (Hans Jansen 7-oct-90) */\n");
fprintf (ofile, "/*****************************************/\n");
fprintf (ofile, "#include <exec/types.h>\n");
fprintf (ofile, "#include <intuition/intuition.h>\n");
CText = AllText;
if (AllText != NULL) {
fprintf (ofile, "\nstruct IntuiText IText[] =\n");
fprintf (ofile, " {\n");
};
while (CText != NULL) { /* for all text to output */
if (CText->NextText == NULL) nxt = ' ';
else nxt = ',';
fprintf (ofile, " { 0, 1, JAM2, CHECKWIDTH, 0, NULL, %c%s%c, NULL }%c\n",
quote, CText->IText, quote, nxt);
CText = CText->NextText;
};
if (AllText != NULL) fprintf (ofile," };\n\n");
CMenu = AllMenu;
Menu = 0;
left = 0;
Item = 0;
height = 10;
while (CMenu != NULL) { /* first output the subitems, if any */
Item = 0;
CItem = CMenu->FirstItem;
while (CItem != NULL) {
CSItem = CItem->SubItem;
if (CSItem != NULL) Do_Out_Sub (Menu,Item);
Item++;
CItem = CItem->NextItem;
};
Menu++;
CMenu = CMenu->NextMenu;
}
CMenu = AllMenu;
Menu = 0;
left = 0;
Item = 0;
height = 10;
while (CMenu != NULL) { /* now output the items */
Item = 0;
CItem = CMenu->FirstItem;
CSItem = CItem->SubItem;
top = 0;
fprintf (ofile, "struct MenuItem M%d[] = \n",Menu);
fprintf (ofile, " {\n");
top = 0;
width = CMenu->Width * CHAR_WIDTH;
while (CItem != NULL) {
Item++;
CSItem = CItem->SubItem;
if (CItem->NextItem == NULL) fprintf (ofile, " {NULL, ");
else fprintf (ofile, " {&M%d[%2d], ", Menu, Item);
fprintf (ofile, "%3d, %3d, %3d+CHECKWIDTH, %3d,\n",
left, top, width, height);
fprintf (ofile, " ITEMTEXT|HIGHCOMP");
if ((CItem->Flags & ENABLE) == ENABLE) fprintf (ofile, "|ITEMENABLED");
if ((CItem->Flags & TOGGLE) == TOGGLE) fprintf (ofile, "|MENUTOGGLE");
if ((CItem->Flags & CHECK) == CHECK) fprintf (ofile, "|CHECKIT");
if ((CItem->Flags & SELECT) == SELECT) fprintf (ofile, "|CHECKED");
if (CItem->Command != NULL && CItem->Command != ' ')
fprintf (ofile, "|COMMSEQ");
fprintf (ofile, ",\n 0, (APTR)&IText[%2d], ",
Index(CItem->ItemFill));
if (CItem->SelectFill == NULL) fprintf (ofile, "NULL, ");
else fprintf (ofile, "(APTR)&IText[%2d], ", Index(CItem->SelectFill));
if (CItem->Command == NULL || CItem->Command == ' ')
fprintf (ofile, "NULL, ");
else fprintf (ofile, "'%c', ", CItem->Command);
if (CSItem == NULL) fprintf (ofile, "NULL, MENUNULL}");
else fprintf (ofile, "&M%dI%d[0], MENUNULL}", Menu, (Item-1));
if (CItem->NextItem == NULL) fprintf (ofile, "\n");
else fprintf (ofile, ",\n");
CItem = CItem->NextItem;
top = top + height;
};
fprintf (ofile, " };\n\n");
CMenu = CMenu->NextMenu;
Menu++;
};
CMenu = AllMenu;
fprintf (ofile, "struct Menu TheMenu[] =\n");
fprintf (ofile, " {\n");
left = 0;
top = 0;
Menu = 0;
while (CMenu != NULL) { /* finally, the menus themselves */
Menu++;
width = CMenu->Width * CHAR_WIDTH;
if (CMenu->NextMenu == NULL) { /* the NextMenu pointer */
sprintf (Mptr, "NULL ");
nxt = ' ';
}
else {
sprintf (Mptr, "&TheMenu[%2d]", Menu);
nxt = ',';
};
(void) strncpy (rest, " ", 25);
stop = CMenu->Width - strlen (CMenu->MenuName); /* the name string */
if (stop <= 0)
(void) strncpy (rest, CMenu->MenuName, 25);
else {
stop = stop / 2;
(void) strncpy (&rest[stop], CMenu->MenuName, 25-stop);
(void) strncat (rest, " ", 25);
};
quote = '"';
height = 10;
fprintf (ofile, " {%12s, %3d, %3d, %3d+CHECKWIDTH, %3d,\n",
Mptr, left, top, width, height);
if ((CMenu->Flags & ENABLE) == ENABLE)
fprintf (ofile, "MENUENABLED");
else
fprintf (ofile, "0");
fprintf (ofile, ",%c%s%c, &M%d[0]}%c\n",
quote, rest, quote, (Menu-1), nxt);
left = left + width + 4*CHAR_WIDTH;
CMenu = CMenu->NextMenu;
};
fprintf (ofile, " };\n\n");
fprintf (ofile, "struct Menu *MyMenu = &TheMenu[0];\n\n");
fprintf (ofile, "/*****************************************/\n");
fprintf (ofile, "/* End of generated code */\n");
fprintf (ofile, "/*****************************************/\n");
fclose (ofile);
}
int Index (ptr) /* Find the position index */
struct IntuiText *ptr;
{
int idx;
idx = 0;
CText = AllText;
while (CText != NULL && ptr != CText) {
idx++;
CText = CText->NextText;
};
return (idx);
}
Do_Out_Sub (Menu, Item) /* output an item's SubItems */
int Menu, Item;
{
int SItem;
int stop, width, sleft;
int top, height;
char Mptr[14];
char rest[60];
char nxt, Flag[10];
SItem = 0;
top = 0;
height = 10;
fprintf (ofile, "struct MenuItem M%dI%d[] = \n", Menu, Item);
fprintf (ofile, " {\n");
width = CMenu->Width*CHAR_WIDTH;
SItem = 0;
while (CSItem != NULL) {
SItem++;
sleft = (width * 7) / 10;
stop = top + 2;
if (CSItem->NextItem == NULL) fprintf (ofile, " {NULL, ");
else fprintf (ofile, " {&M%dI%d[%2d], ", Menu, Item, SItem);
fprintf (ofile, "%3d, %3d, %3d+CHECKWIDTH, %3d,\n",
sleft, stop, width, height);
fprintf (ofile, " ITEMTEXT|HIGHCOMP");
if ((CSItem->Flags & ENABLE) == ENABLE) fprintf (ofile, "|ITEMENABLED");
if ((CSItem->Flags & TOGGLE) == TOGGLE) fprintf (ofile, "|MENUTOGGLE");
if ((CSItem->Flags & CHECK) == CHECK) fprintf (ofile, "|CHECKIT");
if ((CSItem->Flags & SELECT) == SELECT) fprintf (ofile, "|CHECKED");
if (CSItem->Command != NULL && CSItem->Command != ' ')
fprintf (ofile, "|COMMSEQ");
fprintf (ofile, ",\n 0, (APTR)&IText[%2d], ",
Index(CSItem->ItemFill));
if (CSItem->SelectFill == NULL) fprintf (ofile, "NULL, ");
else fprintf (ofile, "(APTR)&IText[%2d], ", Index(CSItem->SelectFill));
if (CSItem->Command == NULL || CSItem->Command == ' ')
fprintf (ofile, "NULL, ");
else fprintf (ofile, "'%c', ", CSItem->Command);
fprintf (ofile, "NULL, MENUNULL}");
if (CSItem->NextItem == NULL) fprintf (ofile, "\n");
else fprintf (ofile, ",\n");
CSItem = CSItem->NextItem;
top = top + height;
};
fprintf (ofile," };\n\n");
}